﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace DevTools.ClassStuffGenerator.Components
{
    public static class Reflector
    {
        public static List<Item> Load(string assemblyPath)
        {
            var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
            foreach (var assemblyName in assembly.GetReferencedAssemblies())
            {
                try
                {
                    Assembly.ReflectionOnlyLoad(assemblyName.FullName);
                }
                catch
                {
                    try
                    {
                        Assembly.ReflectionOnlyLoadFrom(Path.Combine(Path.GetDirectoryName(assemblyPath), assemblyName.Name + ".dll"));
                    }
                    catch
                    {
                    }
                }
            }

            List<Item> items = new List<Item>();
            Type[] allTypes = assembly.GetTypes();

            foreach (var classType in allTypes)
            {
                if (classType.IsClass == false)
                    continue;

                // 익명 타입 혹은 포함된 타입은 제외한다. 
                // TODO : 익명 타입을 체크하는 정확한 로직이 필요
                if (classType.FullName.Contains("<") || classType.FullName.Contains("+"))
                    continue;

                Item @class = Item.Create(classType, null, null);
                items.Add(@class);

                var fieldTypes = classType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                foreach (var fieldInfo in fieldTypes)
                {
                    string fullName = fieldInfo.FieldType.FullName;
                    if (fullName == null || fullName.Contains("<") || fullName.Contains("+"))
                        continue;

                    Item.Create(classType, fieldInfo, @class);
                }
            }

            return items;
        }
    }
}
